#include <QTreeWidgetItem>
#include <QModelIndex>
#include <QTableView>

#include "breakpointsmanager.h"
#include "editortabwidget.h"
#include "meditor.h"
#include "mainwindow.h"

BreakpointsManager::BreakpointsManager (MainWindow *p)
    :QDialog (p)
{
    setupUi(this);

    m_editorTab = p->getEditorTab();

    MEditor *e = 0;
    for (int i = 0; i < m_editorTab->count(); i++) {
        e = m_editorTab->editor(i);
        QString f = e->getFileName();
        comboBox->insertItem(i, f.section('/', -1));
        comboBox->setItemData(i, f, Qt::ToolTipRole);
    }
    connect (comboBox, SIGNAL(currentIndexChanged(int)),
             this, SLOT(selectFile(int)));

    comboBox->setCurrentIndex(m_editorTab->currentIndex());

    connect (this, SIGNAL(delSignal(QString,int)),
             p, SLOT(slotToggleBreakpoint(QString,int)));
    connect (this, SIGNAL(conditionChanged(QString,int,QString)),
             p, SLOT(toConditional(QString,int,QString)));
    connect (buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()),
             this, SLOT(applyChange()));
}

BreakpointsManager::~BreakpointsManager()
{
    foreach (DataLine *l, m_datas) {
        delete l;
    }
}

void BreakpointsManager::selectFile(int i)
{
    QString f = comboBox->itemData(i, Qt::ToolTipRole).toString();
    MEditor *e = m_editorTab->editor(f);
    QMap<int, QString> map;
    e->getAllBreakpoints(map);

    foreach (DataLine *l, m_datas) {
        breakpointsLayout->removeWidget(l->number);
        breakpointsLayout->removeWidget(l->line);
        breakpointsLayout->removeWidget(l->condition);
        delete l;
    }
    m_datas.clear();

    if (map.isEmpty())
        breakpointsLayout->setColumnMinimumWidth(0, 46);
    else
        breakpointsLayout->setColumnMinimumWidth(0, 40);
    int c = 1;
    for (QMap<int, QString>::Iterator i = map.begin(); i != map.end(); i++, c++) {
        DataLine *l = new DataLine(c, i.key(), i.value());
        breakpointsLayout->addWidget(l->number, c, 0);
        breakpointsLayout->addWidget(l->line, c, 1);
        breakpointsLayout->addWidget(l->condition, c, 2);
        breakpointsLayout->addWidget(l->deleteState, c, 3);
        m_datas.append(l);
    }
}

void BreakpointsManager::selectAll()
{
    foreach (DataLine *l, m_datas) {
        l->checkBox->setChecked(true);
    }
}

void BreakpointsManager::selectInvert()
{
    foreach (DataLine *l, m_datas) {
        l->checkBox->setChecked(!(l->checkBox->isChecked()));
    }
}

void BreakpointsManager::deleteSelected()
{
    foreach (DataLine *l, m_datas) {
        if (l->checkBox->isChecked()) {
            emit delSignal(currentFilename(), l->line->text().toInt());
        }
    }
    selectFile(comboBox->currentIndex());
}

void BreakpointsManager::applyChange()
{
    QString f = comboBox->itemData(comboBox->currentIndex(), Qt::ToolTipRole).toString();
    foreach (DataLine *l, m_datas) {
        if (l->deleteIsDirty())
            emit delSignal(f, l->line->text().toInt());
        else if (l->conditionIsDirty())
            emit conditionChanged(f, l->line->text().toInt(), l->condition->text());
    }
    selectFile(comboBox->currentIndex());
}

QString BreakpointsManager::currentFilename()
{
    return comboBox->itemData(comboBox->currentIndex(), Qt::ToolTipRole).toString();
}

DataLine::DataLine(int n, int l, QString c)
{
    checkBox    = new QCheckBox();
    number      = new QLabel(QString::number(n)+"   ");
    number->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    number->setFrameShape(QFrame::StyledPanel);
    line        = new QLabel(QString::number(l)+"   ");
    line->setFrameShape(QFrame::StyledPanel);
    line->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    condition   = new QLineEdit(c);
    deleteState = new QPushButton(QIcon(":/images/breakpoints/no.png"), "");
    deleteState->setCheckable(true);
    connect(deleteState, SIGNAL(toggled(bool)),
                     condition, SLOT(setDisabled(bool)));
    connect(deleteState, SIGNAL(toggled(bool)),
                     this, SLOT(toggleState(bool)));
    connect(condition, SIGNAL(textChanged(QString)),
            this, SLOT(makeConditionDirty(QString)));
}

DataLine::~DataLine()
{
    delete checkBox;
    delete number;
    delete line;
    delete condition;
    delete deleteState;
}

bool DataLine::selected()
{
    return checkBox->isChecked();
}

void DataLine::toggleState(bool checked)
{
    if (checked)
        deleteState->setIcon(QIcon(":/images/breakpoints/restore.png"));
    else
        deleteState->setIcon(QIcon(":/images/breakpoints/no.png"));
}

void DataLine::makeConditionDirty(QString)
{
    conditionDirty = true;
    disconnect(condition, SIGNAL(textChanged(QString)),
               this, SLOT(makeConditionDirty(QString)));
}

bool DataLine::deleteIsDirty()
{
    return deleteState->isChecked();
}

bool DataLine::conditionIsDirty()
{
    return conditionDirty;
}
